package com.nananren.aop;

import com.alibaba.fastjson.JSONObject;
import com.nananren.common.MyThreadLocal;
import com.nananren.domain.OperateLog;
import com.nananren.service.OperateLogService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Arrays;

@Aspect
@Component
@Slf4j
public class OperateLogAspect {

    @Autowired
    private OperateLogService operateLogService;

//    @Pointcut("@annotation(com.nananren.anno.OperateLogLog)")
//    public void pt2(){}

    @Pointcut("execution(* com.nananren.controller.*Controller.save*(..)) "
            + "|| execution(* com.nananren.controller.*Controller.delete*(..))"
            + "|| execution(* com.nananren.controller.*Controller.update*(..))"
            + "|| execution(* com.nananren.controller..*Controller.login*(..))")
    public void pt3(){}

    @Around("pt3()")
    public Object recordLog(ProceedingJoinPoint joinPoint) throws Throwable {
        // 获得操作人id
        Long operateId = MyThreadLocal.getLocal();

        // 获得目标方法方法名
        String operateMethod = joinPoint.getSignature().getName();

        // 获得目标方法类名
        String operateClass = joinPoint.getTarget().getClass().getName();
//        log.info("{}", operateClass);

        // 获得操作的方法传入的参数
        Object[] args = joinPoint.getArgs();
        String operateArgs = Arrays.toString(args);

        // 记录方法开始时间
        long begin = System.currentTimeMillis();
        // 获得方法返回值
        Object result = joinPoint.proceed();
        String operateResult = JSONObject.toJSONString(result);
        // 记录方法结束时间
        long end = System.currentTimeMillis();
        // 花费时间
        Long costTime = end - begin;

        // 日志创建时间
        LocalDateTime createTime = LocalDateTime.now();
        // 插入日志
        OperateLog operateLog = new OperateLog(null, operateId, operateMethod, operateClass, operateArgs,
                operateResult, costTime, createTime);
        operateLogService.save(operateLog);
        log.info("{}, {}, {}, {}, {}, {}, {}",
                operateId, operateMethod, operateClass, operateArgs, operateResult, costTime + "ms", createTime);

        return result;
    }

}
